package org.c41.graphics.effect;

import java.util.ArrayList;

import org.c41.graphics.C41Graphic;
import org.c41.system.ImpossibleException;

public abstract class Effect implements Updatable, Paintable {

	private static final int READY = 1000;
	private static final int RUNNING = 1001;
	private static final int COMPLETED = 1002;
	
	private ArrayList<EffectListener> listeners = new ArrayList<>();
	private int state = READY;
	
	@Override
	public final void  paint(C41Graphic g){
		switch(this.state){
		case READY:	paintReady(g);break;
		case RUNNING: paintEffect(g);break;
		case COMPLETED: paintCompleted(g);break;
		default: throw new ImpossibleException();
		}
	}
	
	@Override
	public final void update(long during){
		if(isEffecting()){
			updateEffect(during);
		}
	}
	
	public abstract void updateEffect(long during);
	
	public abstract void paintReady(C41Graphic g);
	public abstract void paintEffect(C41Graphic g);
	public abstract void paintCompleted(C41Graphic g);

	public final boolean isReady(){
		return this.state==READY;
	}

	public final boolean isEffecting(){
		return this.state==RUNNING;
	}
	
	public final boolean isCompleted(){
		return this.state==COMPLETED;
	}
	
	public final void begin(){
		if(isReady()){
			this.state=RUNNING;
		}
	}

	public final void addEffectListener(EffectListener l){
		this.listeners.add(l);
	}
	
	public final void removeEffectListener(EffectListener l){
		this.listeners.remove(l);
	}
	
	protected void complete(){
		if(state==RUNNING){
			state=COMPLETED;
			for(EffectListener l:listeners){
				l.onEffectCompelete(this);
			}
		}
	}
	
}
